import { Big, MC, RoundingMode } from 'bigdecimal.js';

type TStringOrNumber = number | string;

/**
 * @desc 转换为百分比并默认保留两位小数
 * @param num {Number}
 * @param precision {Number} 保存的小数位数，默认两位
 * @returns x.xx%
 */
export const toPercent = (num: TStringOrNumber, precision = 2) => {
  return (parseFloat(num as string) * 100).toFixed(precision) + '%';
};

export const multiply100 = (val: TStringOrNumber) => {
  return parseFloat(Big(val).multiply(100).toString());
};

/**
 * 数值千分位转换 默认按en-US格式转换
 * @param num1 数值
 * @param decimal 保留的小数位数(默认自适应当前小数位数)
 */
export function toNumLocaleString(
  num1: TStringOrNumber,
  decimal?: number
): string {
  let num = Number(num1);
  if (isNaN(num) === true) {
    return num1 + '';
  }
  let minimumFractionDigits = 0;
  if (decimal === undefined) {
    const [, decimalStr = ''] = num1.toString().split('.');
    minimumFractionDigits = decimalStr.length;
  } else {
    if (decimal < 0) {
      decimal = 0;
    }
    minimumFractionDigits = decimal;
  }
  return num.toLocaleString('en-US', { minimumFractionDigits, maximumFractionDigits: minimumFractionDigits });
}

export function numThousandthFilter(number:TStringOrNumber, minimumFractionDigits?: number, maximumFractionDigits?: number) {
  maximumFractionDigits = Math.max(minimumFractionDigits || 2, maximumFractionDigits || 2);
  return parseFloat(number as string).toLocaleString('en-us', {
    maximumFractionDigits: maximumFractionDigits || 2,
    minimumFractionDigits: minimumFractionDigits || 2
  });
}

const fnMap = {
  AMOUNT: numThousandthFilter,
  PERCENT: toPercent,
  NUMBER100: multiply100
};

export const formatter = (val: any, type: keyof typeof fnMap) => {
  if (val === 0) return val;
  if (!val) return '-';
  return fnMap[type](val);
};

// 精准加法
export const plus = (num1: TStringOrNumber, num2: TStringOrNumber) => {
  const x = Big(num1);
  const y = Big(num2);
  const result = x.add(y).toString();
  return parseFloat(result);
};

// 精准减法
export const minus = (num1: TStringOrNumber, num2: TStringOrNumber) => {
  const x = Big(num1);
  const y = Big(num2);
  const resultStr = x.subtract(y).toString();
  return parseFloat(resultStr);
};

// 精准乘法
export const multiply = (num1: TStringOrNumber, num2: TStringOrNumber) => {
  const x = Big(num1);
  const y = Big(num2);
  const result = x.multiply(y).toString();
  return parseFloat(result);
};

// 精准除法
export const divide = (num1: TStringOrNumber, num2: TStringOrNumber, length = 4) => {
  const x = Big(num1);
  const y = Big(num2);
  const result = x.divideWithMathContext(y, new MC(length, RoundingMode.UP)).toString();
  return parseFloat(result);
};

export const divide100 = (num1: TStringOrNumber) => {
  return divide(num1, 100, 2);
};

export const round = (num: TStringOrNumber, length = 2) => {
  return parseFloat(Big(num).round(new MC(length, RoundingMode.HALF_UP)).toString());
};